Skip to content
honteam  /   Heroes-of-Newerth...  /   Pull requests #72  /  
Open in github.dev Open in a new github.dev tab Open in codespace
Code

Electrician Bot Submission #72

Open
wants to merge 3 commits into
base: Community
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
0 / 2 files viewed
9 changes: 9 additions & 0 deletions bots/electrician/electrician.bot
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<bot
name="ElectroBot"
description="An Electrician Bot by CASHBALLER."
heroname="Hero_Electrician"
rootlua="electrician_main.lua"
defaultplayername="ElectricianBot"
precachepath="/heroes/electrician/"
/>
569 changes: 569 additions & 0 deletions bots/electrician/electrician_main.lua
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,569 @@
--[[
ElectroBot v1.2
by CASHBALLER
---------------------------------------------------
-- Recent Changes
---------------------------------------------------
----- 1.2 -----
- Functionality
-- Now purges some dangerous summoned units
-- Starts with Logger's Hatchet
----- 1.1 -----
- Functionality
-- Now purges debuffs on allies and speed buffs on enemies
-- Updated lane preferences
- Code
-- Removed object.nGameTime
-- Renamed val to nUtility
-- Updated SkillBuild function
-- Moved constants around for readability (thanks HagBot)
-- Added bActionTaken back in
---------------------------------------------------
-- Notes
---------------------------------------------------
- Static Grip
-- used offensively when harass utility is high
-- sometimes stops channelling right after starting (seems to be a problem with other bots too)

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To stop this At the start of harassHeroExecuteOverride
if unitSelf:IsChanneling() then
return true
end

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred

- Electric Shield
-- used offensively with very high harass utility or high mana remaining
-- used defensively when health is relatively low compared to mana
-- gave it a short cooldown to prevent spamming
- Energy Absorption
-- used often with low harass utility threshold (maybe too aggressive for new players)
-- used during retreat for speed boost
- Cleansing Shock
-- used to remove perplex/snares/slows/silence from nearby allies
-- used to purge some deadly enemy summoned units
-- used to remove haste from nearby enemies (need to improve this to check states)
-- used offensively with high harass utility
-- if target is out of range, may use on self for speed boost (very high harass utility)
-- used defensively whenever slowed or snared
-- used to return to well faster
- General
-- should increase well return utility when mana is very low, since he's useless without it
-- harass utility could also use some changes to reflect remaining mana
-- ability weights probably could use adjustments, but these work fairly well
-- to implement: Cleansing Shock enemy summoned units
- Code
-- using a single variable (bDebugLocal) instead of a different bDebugEchos in every method
-- CustomReturnToWellExecute would not work, so overriding HealAtWellExecute instead
--]]


local _G = getfenv(0)
local object = _G.object

-- Set to true for local debug echo messages
local bDebugLocal = false

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the bot no longer in heavy development, all the debugging prints (that use bDebugLocal) should be removed, along with bDebugLocal - because there are 38 of them :)

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred


object.myName = object:GetName()

object.bRunLogic = true
object.bRunBehaviors = true
object.bUpdates = true
object.bUseShop = true

object.bRunCommands = true
object.bMoveCommands = true
object.bAttackCommands = true
object.bAbilityCommands = true
object.bOtherCommands = true

object.bReportBehavior = false
object.bDebugUtility = false
object.bDebugExecute = false

object.logger = {}
object.logger.bWriteLog = false
object.logger.bVerboseLog = false

object.core = {}
object.eventsLib = {}
object.metadata = {}
object.behaviorLib = {}
object.skills = {}

runfile "bots/core.lua"
runfile "bots/botbraincore.lua"
runfile "bots/eventsLib.lua"
runfile "bots/metadata.lua"
runfile "bots/behaviorLib.lua"

local core, eventsLib, behaviorLib, metadata, skills = object.core, object.eventsLib, object.behaviorLib, object.metadata, object.skills

local print, ipairs, pairs, string, table, next, type, tinsert, tremove, tsort, format, tostring, tonumber, strfind, strsub
= _G.print, _G.ipairs, _G.pairs, _G.string, _G.table, _G.next, _G.type, _G.table.insert, _G.table.remove, _G.table.sort, _G.string.format, _G.tostring, _G.tonumber, _G.string.find, _G.string.sub
local ceil, floor, pi, tan, atan, atan2, abs, cos, sin, acos, max, random
= _G.math.ceil, _G.math.floor, _G.math.pi, _G.math.tan, _G.math.atan, _G.math.atan2, _G.math.abs, _G.math.cos, _G.math.sin, _G.math.acos, _G.math.max, _G.math.random

local BotEcho, VerboseLog, BotLog = core.BotEcho, core.VerboseLog, core.BotLog
local Clamp = core.Clamp

BotEcho('loading electrician_main...')

---------------------------------------------------
-- Constants
---------------------------------------------------

object.heroName = 'Hero_Electrician'

-- Lanes
core.tLanePreferences = {Jungle = 0, Mid = 1, ShortSolo = 1, LongSolo = 1, ShortSupport = 3, LongSupport = 3, ShortCarry = 3, LongCarry = 3}

-- Items (internal names)
behaviorLib.StartingItems = {"Item_RunesOfTheBlight", "Item_LoggersHatchet", "Item_IronBuckler"}
behaviorLib.LaneItems = {"Item_Marchers", "Item_ManaRegen3", "Item_MysticVestments", "Item_Shield2"}
behaviorLib.MidItems = {"Item_EnhancedMarchers", "Item_Replenish", "Item_NomesWisdom", "Item_HealthMana2"}
behaviorLib.LateItems = {"Item_Protect", "Item_SolsBulwark", "Item_DaemonicBreastplate", "Item_BehemothsHeart"}

-- Skillbuild table, 0 = q, 1 = w, 2 = e, 3 = r, 4 = attri
object.tSkills = {
0, 2, 2, 0, 2,
3, 2, 0, 0, 1,
3, 1, 1, 1, 4,
3, 4, 4, 4, 4,
4, 4, 4, 4, 4
}

-- Bonus agression points if a skill/item is available for use
object.nStaticGripUp = 12
object.nEnergyAbsorptionUp = 20
object.nCleansingShockUp = 10

-- Bonus agression points that are applied to the bot upon successfully using a skill/item
object.nStaticGripUse = 28
object.nElectricShieldUse = 18
object.nEnergyAbsorptionUse = 0
object.nCleansingShockUse = 16

-- Thresholds of aggression the bot must reach to use these abilities
object.nStaticGripLowThreshold = 39 -- use more freely when mana > 250 since we can still absorb/shock after
object.nStaticGripHighThreshold = 52 -- stricter usage when low mana
object.nElectricShieldLowThreshold = 38 -- high mana remaining - use freely
object.nElectricShieldMedThreshold = 56 -- medium mana remaining - use sparingly
object.nElectricShieldHighThreshold = 74 -- low mana remaining - only use if very aggressive
object.nEnergyAbsorptionThreshold = 10
object.nCleansingShockThreshold = 42
object.nCleansingShockSelfThreshold = 64 -- used to determine if the self speed boost is more important than waiting to get in range for the slow

-- Stores game time at which shield can be cast again (not constant)
object.nShieldCooldown = 0

---------------------------------------------------
-- Skills
---------------------------------------------------
function object:SkillBuild()
local unitSelf = self.core.unitSelf
if skills.abilStaticGrip == nil then
skills.abilStaticGrip = unitSelf:GetAbility(0)
skills.abilElectricShield = unitSelf:GetAbility(1)
skills.abilEnergyAbsorption = unitSelf:GetAbility(2)
skills.abilCleansingShock = unitSelf:GetAbility(3)
skills.abilAttributeBoost = unitSelf:GetAbility(4)
end

local nPoints = unitSelf:GetAbilityPointsAvailable()
if nPoints <= 0 then
return
end

local nLevel = unitSelf:GetLevel()
for i = nLevel, (nLevel + nPoints) do
unitSelf:GetAbility( self.tSkills[i] ):LevelUp()
end
end

---------------------------------------------------
-- OnCombatEvent Override
---------------------------------------------------
function object:oncombateventOverride(EventData)
self:oncombateventOld(EventData)

local nAddBonus = 0

if EventData.Type == "Ability" then
if bDebugLocal then BotEcho("Combat Event - InflictorName: "..EventData.InflictorName) end
if EventData.InflictorName == "Ability_Electrician1" then
nAddBonus = nAddBonus + object.nStaticGripUse
elseif EventData.InflictorName == "Ability_Electrician2" then
nAddBonus = nAddBonus + object.nElectricShieldUse
elseif EventData.InflictorName == "Ability_Electrician3" then
nAddBonus = nAddBonus + object.nEnergyAbsorptionUse
elseif EventData.InflictorName == "Ability_Electrician4" then
nAddBonus = nAddBonus + object.nCleansingShockUse
end
end

if nAddBonus > 0 then
--decay before we add
core.DecayBonus(self)
core.nHarassBonus = core.nHarassBonus + nAddBonus
end
end
object.oncombateventOld = object.oncombatevent
object.oncombatevent = object.oncombateventOverride

---------------------------------------------------
-- CustomHarassUtility Override
---------------------------------------------------
local function CustomHarassUtilityOverride(hero)

local nUtility = 0

if skills.abilStaticGrip:CanActivate() then
nUtility = nUtility + object.nStaticGripUp
end

if skills.abilEnergyAbsorption:CanActivate() then
nUtility = nUtility + object.nEnergyAbsorptionUp
end

if skills.abilCleansingShock:CanActivate() then
nUtility = nUtility + object.nCleansingShockUp
end

return nUtility
end
behaviorLib.CustomHarassUtility = CustomHarassUtilityOverride

---------------------------------------------------
-- Electric Shield
---------------------------------------------------
local function checkElectricShieldCooldown()
local nGameTime = HoN.GetGameTime()
if bDebugLocal then BotEcho("ShieldCheck - Checking Shield cooldown at: "..nGameTime) end
if nGameTime > object.nShieldCooldown then
if bDebugLocal then BotEcho("ShieldCheck - - Shield ready") end
return true
end
return false
end

-- Short cooldown on shield to prevent spamming
local function activateElectricShield(botBrain, bDebugEchos)
local nGameTime = HoN.GetGameTime()
if bDebugEchos then BotEcho("ShieldActivate - Shield casting at: "..nGameTime) end
object.nShieldCooldown = nGameTime + 4000 -- four second cooldown
return core.OrderAbility(botBrain, skills.abilElectricShield, false, bDebugEchos)
end

---------------------------------------------------
-- List of Summoned Minions to Purge
---------------------------------------------------
local function isPurgeablePet(sName)
-- Add Coeurl and Shiver?
-- Other minions aren't really worth using the ult cooldown on
if sName == "Pet_Hellbringer_Ability4" or sName == "Pet_Hellbringer_Ability4_Alt" or sName == "Pet_Hellbringer_Ability4_Alt2" or sName == "Pet_Hellbringer_Ability4_Alt3" or sName == "Pet_NecroRanged" then

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would probably be better if it tried all pets above a certain amount of hp, say, 600, with something like:
strfind(sName, "Pet_") ~= nil and hp > 600

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred

return true
end
return false
end

---------------------------------------------------
-- Cleansing Shock TargetFinder
---------------------------------------------------
local function findPurgeTarget(botBrain, unitSelf)
local tNearbyUnits = HoN.GetUnitsInRadius(unitSelf:GetPosition(), 600, core.UNIT_MASK_ALIVE + core.UNIT_MASK_HERO + core.UNIT_MASK_UNIT)

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would throttle this, only having it call 2-3 times every second or something - because currently at 20 times a second whenever it is off cooldown, would cause a bit of a slowdown on HoN servers

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred

local tSortedUnits = {}
core.SortUnitsAndBuildings(tNearbyUnits, tSortedUnits, false)
local unitPurgePerplex = nil
local unitPurgeSnare = nil
local unitPurgeSlow = nil
local unitPurgeSilence = nil
local nSlowSpeed = 275

-- Check nearby allies for debuffs we can purge
for nUID,unitAlly in pairs(tSortedUnits.allyHeroes) do
if unitAlly:IsPerplexed() then
unitPurgePerplex = unitAlly
end
if unitAlly:IsImmobilized() then
unitPurgeSnare = unitAlly
end
local nUnitSpeed = unitAlly:GetMoveSpeed()
if nUnitSpeed < nSlowSpeed then
unitPurgeSlow = unitAlly
nSlowSpeed = nUnitSpeed
end
if unitAlly:IsSilenced() then
unitPurgeSilence = unitAlly
end
end

-- Purge debuffs if any exist
if unitPurgePerplex ~= nil then
if bDebugLocal then BotEcho("PurgeFinder - Targeting ally to remove perplex") end
return unitPurgePerplex
elseif unitPurgeSnare ~= nil then
if bDebugLocal then BotEcho("PurgeFinder - Targeting ally to remove snare") end
return unitPurgeSnare
elseif unitPurgeSlow ~= nil then
if bDebugLocal then BotEcho("PurgeFinder - Targeting ally to remove slow") end
return unitPurgeSlow
elseif unitPurgeSilence ~= nil then
if bDebugLocal then BotEcho("PurgeFinder - Targeting ally to remove silence") end
return unitPurgeSilence
else

-- Next check for dangerous enemy summoned units
for nUID,unitEnemy in pairs(tSortedUnits.enemyCreeps) do
local sName = unitEnemy:GetTypeName()
if isPurgeablePet(sName) then
if bDebugLocal then BotEcho("PurgeFinder - Targeting summoned unit to destroy: "..sName) end
return unitEnemy
end
end

-- Otherwise check for hasted enemies
for nUID,unitEnemy in pairs(tSortedUnits.enemyHeroes) do
if (unitEnemy:GetMoveSpeed() > 500 or unitEnemy:IsStealth()) and botBrain.CanSeeUnit(unitEnemy) then
if bDebugLocal then BotEcho("PurgeFinder - Targeting enemy to remove speed buff") end
return unitEnemy
end
end
end
end

---------------------------------------------------
-- Custom minion attack behavior
---------------------------------------------------
local function AttackEnemyMinionsExecuteOverride(botBrain)

local bActionTaken = false
local unitSelf = core.unitSelf
local unitMinionTarget = core.unitMinionTarget

if not bActionTaken then
local sName = unitMinionTarget:GetTypeName()
-- Might as well ult the exploding minion if we're going to attack it anyway
if isPurgeablePet(sName) or sName == "Pet_NecroMelee" then

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random thought, why didn't you put 'Pet_NecroMelee' into isPurgeablePet? Would make more sense : D

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred

local abilCleansingShock = skills.abilCleansingShock
if abilCleansingShock:CanActivate() then
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitMinionTarget)
end
end
end

if not bActionTaken then
return object.attackEnemyMinionsOld(botBrain)
end

return bActionTaken
end
object.attackEnemyMinionsOld = behaviorLib.attackEnemyMinionsBehavior["Execute"]
behaviorLib.attackEnemyMinionsBehavior["Execute"] = AttackEnemyMinionsExecuteOverride

---------------------------------------------------
-- Electrician harass actions
---------------------------------------------------
local function HarassHeroExecuteOverride(botBrain)

local bActionTaken = false
local unitTarget = behaviorLib.heroTarget
if unitTarget == nil or not unitTarget:IsValid() then
if bDebugLocal then BotEcho("HarassHero - No target") end
return object.harassExecuteOld(botBrain)
end

local unitSelf = core.unitSelf
local nLastHarassUtility = behaviorLib.lastHarassUtil
if bDebugLocal then BotEcho("HarassHero - Utility: "..nLastHarassUtility) end

if unitSelf:IsChanneling() then
if bDebugLocal then BotEcho("HarassHero - Channeling...") end
local abilElectricShield = skills.abilElectricShield
if abilElectricShield:CanActivate() and checkElectricShieldCooldown() then
local nManaPercent = unitSelf:GetManaPercent()
if nLastHarassUtility > botBrain.nElectricShieldLowThreshold and nManaPercent > 0.8 then
if bDebugLocal then BotEcho("HarassHero - - Channeling and have extra mana, using Electric Shield!") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
elseif nLastHarassUtility > botBrain.nElectricShieldMedThreshold and nManaPercent > 0.4 then
if bDebugLocal then BotEcho("HarassHero - - Channeling and have mana, using Electric Shield!") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
elseif nLastHarassUtility > botBrain.nElectricShieldHighThreshold then
if bDebugLocal then BotEcho("HarassHero - - Channeling and using Electric Shield!") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
end

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are gonna take out prints, each of these clauses do the same thing, so it would make sense to chain or's, e.g.
if X or
Y or
Z then
...

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred

end
return bActionTaken
end

local vecMyPosition = unitSelf:GetPosition()
local vecTargetPosition = unitTarget:GetPosition()
local nTargetDistanceSq = Vector3.Distance2DSq(vecMyPosition, vecTargetPosition)

-- Energy Absorption
if not bActionTaken and nLastHarassUtility > botBrain.nEnergyAbsorptionThreshold then
local abilEnergyAbsorption = skills.abilEnergyAbsorption
if bDebugLocal then BotEcho("HarassHero - - Checking Energy Absorption range and activatable...") end
if abilEnergyAbsorption:CanActivate() and nTargetDistanceSq < (300 * 300) then
if bDebugLocal then BotEcho("HarassHero - - - Harassing with Energy Absorption") end
bActionTaken = core.OrderAbility(botBrain, skills.abilEnergyAbsorption, false, bDebugLocal)
end
end

-- Static Grip
if not bActionTaken then
local abilStaticGrip = skills.abilStaticGrip
if abilStaticGrip:CanActivate() then
if bDebugLocal then BotEcho("HarassHero - - Checking Static Grip worth casting...") end
if (nLastHarassUtility > botBrain.nStaticGripHighThreshold or (nLastHarassUtility > botBrain.nStaticGripLowThreshold and unitSelf:GetMana() > 250)) and not (unitTarget:IsStunned() or unitTarget:IsImmobilized()) then
if bDebugLocal then BotEcho("HarassHero - - - Harassing with Static Grip") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilStaticGrip, unitTarget)
end
end
end

-- Cleansing Shock
if not bActionTaken then
local abilCleansingShock = skills.abilCleansingShock
if abilCleansingShock:CanActivate() then
-- Find nearby heroes to Cleansing Shock
local unitPurgeTarget = findPurgeTarget(botBrain, unitSelf)
if unitPurgeTarget ~= nil then
if bDebugLocal then BotEcho("HarassHero - - Casting Cleansing Shock on nearby hero") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitPurgeTarget)
elseif nLastHarassUtility > botBrain.nCleansingShockThreshold and unitTarget:GetMoveSpeed() > 275 then
if nTargetDistanceSq < (600 * 600) then
if bDebugLocal then BotEcho("HarassHero - - Harassing with Cleansing Shock") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitTarget)
elseif nLastHarassUtility > botBrain.nCleansingShockSelfThreshold then
if bDebugLocal then BotEcho("HarassHero - - Speeding myself up with Cleansing Shock") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitSelf)
else
if bDebugLocal then BotEcho("HarassHero - - Harassing with Cleansing Shock") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitTarget)
end
end
end
end

-- Electric Shield
if not bActionTaken then
local abilElectricShield = skills.abilElectricShield
if nTargetDistanceSq < (300 * 300) and abilElectricShield:CanActivate() and checkElectricShieldCooldown() then
local nManaPercent = unitSelf:GetManaPercent()
if bDebugLocal then BotEcho("HarassHero - - Checking for Electric Shield with mana percent: "..nManaPercent) end
if nLastHarassUtility > botBrain.nElectricShieldLowThreshold and nManaPercent > 0.8 then
if bDebugLocal then BotEcho("HarassHero - - - Harassing with Electric Shield") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
elseif nLastHarassUtility > botBrain.nElectricShieldMedThreshold and nManaPercent > 0.5 then
if bDebugLocal then BotEcho("HarassHero - - - Harassing with Electric Shield") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
elseif nLastHarassUtility > botBrain.nElectricShieldHighThreshold and nManaPercent > 0.3 then
if bDebugLocal then BotEcho("HarassHero - - - Harassing with Electric Shield") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
end
end
end

if not bActionTaken then
if bDebugLocal then BotEcho("HarassHero - - No action yet, proceeding with normal harass execute.") end
return object.harassExecuteOld(botBrain)
end

return bActionTaken
end
object.harassExecuteOld = behaviorLib.HarassHeroBehavior["Execute"]
behaviorLib.HarassHeroBehavior["Execute"] = HarassHeroExecuteOverride

---------------------------------------------------
-- Electrician specific retreat
---------------------------------------------------
local function CustomRetreatExecuteOverride(botBrain)

local bActionTaken = false
local unitSelf = core.unitSelf

-- Use Cleansing Shock if snared (prioritize self)
if not bActionTaken then
local abilCleansingShock = skills.abilCleansingShock
if abilCleansingShock:CanActivate() then
if unitSelf:GetMoveSpeed() < 275 or unitSelf:IsImmobilized() then
if bDebugLocal then BotEcho("Retreat - Using Cleansing Shock to remove snare") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitSelf)
else
-- Find nearby heroes to Cleansing Shock
local unitPurgeTarget = findPurgeTarget(botBrain, unitSelf)
if unitPurgeTarget ~= nil then
if bDebugLocal then BotEcho("Retreat - Casting Cleansing Shock on nearby hero") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitPurgeTarget)
end
end
end
end

-- Use Energy Absorption if we are near any enemy heroes (speed boost + free harass while retreating)
if not bActionTaken then
local abilEnergyAbsorption = skills.abilEnergyAbsorption
if abilEnergyAbsorption:CanActivate() then
local tNearbyUnits = HoN.GetUnitsInRadius(unitSelf:GetPosition(), 300, core.UNIT_MASK_ALIVE + core.UNIT_MASK_HERO)
local tSortedUnits = {}
core.SortUnitsAndBuildings(tNearbyUnits, tSortedUnits, false)
local nNearbyEnemyHeroes = core.NumberElements(tSortedUnits.enemyHeroes)
if bDebugLocal then BotEcho("Retreat - Checking number of nearby enemy heroes: "..nNearbyEnemyHeroes) end
if nNearbyEnemyHeroes > 0 then
if bDebugLocal then BotEcho("Retreat - - Using Energy Absorption to retreat faster") end
bActionTaken = core.OrderAbility(botBrain, abilEnergyAbsorption, false, bDebugLocal)
end
end
end

-- Use Electric Shield if low health and enough extra mana
if not bActionTaken then
local abilElectricShield = skills.abilElectricShield
if abilElectricShield:CanActivate() and checkElectricShieldCooldown() then
if bDebugLocal then BotEcho("Retreat - Checking if we have enough mana for a decent shield") end
if unitSelf:GetManaPercent() > unitSelf:GetHealthPercent() * 2 and unitSelf:GetMana() - unitSelf:GetMaxMana() * 0.2 > 25 then
if bDebugLocal then BotEcho("Retreat - Casting Electric Shield defensively") end
bActionTaken = activateElectricShield(botBrain, bDebugLocal)
end
end
end

return bActionTaken
end
behaviorLib.CustomRetreatExecute = CustomRetreatExecuteOverride

---------------------------------------------------
-- Return to well
---------------------------------------------------
local function HealAtWellExecuteOverride(botBrain)

Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is out-dated, and should use the custom override function, like so:
function behaviorLib.CustomReturnToWellExecute(botBrain)
local bAction = false
local abilDemonicShield = skills.DemonicShield
if abilDemonicShield:CanActivate() then --activate shield when heading back
bAction = core.OrderAbility(botBrain, abilDemonicShield)
end
end

@K-O-N-G-O-R

Select a reply

Slash commands
Beta
Give feedback
Slash commands
Beta
Give feedback

An unexpected error has occurred


local bActionTaken = false
local unitSelf = core.unitSelf

-- Use Cleansing Shock
if not bActionTaken then
local abilCleansingShock = skills.abilCleansingShock
if abilCleansingShock:CanActivate() then
if bDebugLocal then BotEcho("Well Return - Using Cleansing Shock to return faster") end
bActionTaken = core.OrderAbilityEntity(botBrain, abilCleansingShock, unitSelf)
end
end

if not bActionTaken then
return object.healExecuteOld(botBrain)
end

return bActionTaken
end
object.healExecuteOld = behaviorLib.HealAtWellBehavior["Execute"]
behaviorLib.HealAtWellBehavior["Execute"] = HealAtWellExecuteOverride

BotEcho('finished loading electrician_main')